package com.smartboot.plus.ignite;


import com.smartboot.plus.ignite.cache.*;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.affinity.AffinityKey;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.util.typedef.internal.S;

import javax.cache.configuration.Factory;
import javax.cache.expiry.ExpiryPolicy;
import java.util.Set;

/**
 * PARTITIONED：分区模式，数据分散到集群中的各个节点，分区模式适合存储数量庞大的数据 ，能存储海量数据，频繁更新对其影响不大	查询缓存涉及到数据移动，对查询性能有影响
 * REPLICATED：复制模式，有数据再平衡过程，主节点(Primary)数据与分区模式的一致，只是复制模式默认备份了除主节点数据外的其余数据。复制模式适合存储数据量小，增长不快的数据。
 * 适合存储数据量不大的数据，数据查询性能稳定	频繁更新对其影响较大
 */
public enum IgniteCacheRegion {

    /**
     * 连接信息缓存
     * 每个节点维护自己的连接，频繁变更，不适合广播
     */
    MQTT_CLIENT_CACHE("MqttClientCache", "MqttClientCacheRegion",
            CacheMode.PARTITIONED,
            new Class[]{String.class, MqttClientCache.class}) {
        @Override
        public boolean persistence() {
            return false;
        }


        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 1024L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 1;
        }


    },

    /**
     * 鉴权信息（用户名、密码）
     * 全局一致性要求，配置类数据，应由  控制
     * 鉴权敏感数据，需要统一管理、更新后广播到集群
     */
    MQTT_AUTH_CACHE("MqttAuthCache", "MqttAuthCacheRegion", CacheMode.REPLICATED,
            new Class[]{String.class, MqttAuthCache.class}) {
        @Override
        public boolean persistence() {
            return true;
        }

        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 512L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 2;
        }
    },
    /**
     * 节点指标数据
     * 仅用于统计展示，每个节点自己维护
     */
    MQTT_METRIC_CACHE("MqttMetricCache", "MqttMetricCacheRegion", CacheMode.REPLICATED,
            new Class[]{String.class, MqttMetricCache.class}) {
        @Override
        public boolean persistence() {
            return false;
        }


        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 512L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 1;
        }
    },
    /**
     * 节点信息
     */
    MQTT_NODE_CACHE("MqttNodeCache", "MqttNodeCacheRegion", CacheMode.REPLICATED,
            new Class[]{String.class, MqttNodeCache.class}) {
        @Override
        public boolean persistence() {
            return false;
        }


        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 512L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 2;
        }
    },
    /**
     * 主题权限控制列表
     * 安全配置类，需一致性和广播更新
     * ACL 权限控制影响消息投递，需  统一配置和下发
     */
    MQTT_ACL_CACHE("MqttAclCache", "MqttACLCacheRegion", CacheMode.REPLICATED,
            new Class[]{String.class, MqttAclCache.class}) {
        @Override
        public boolean persistence() {
            return true;
        }

        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 1024L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 2;
        }
    },
    //nodeTopics  topicNodes
    MQTT_TOPIC_NODES_CACHE("MqttTopicNodesCache", "MqttTopicNodesCacheRegion", CacheMode.PARTITIONED,
            new Class[]{String.class, Set.class}) {
        @Override
        public boolean persistence() {
            return false;
        }

        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 1024L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 1;
        }
    },
    MQTT_NODE_TOPIC_CLIENTS_CACHE("MqttNodeTopicClientsCache", "MqttNodeTopicClientsCacheRegion", CacheMode.PARTITIONED,
            new Class[]{String.class,  AffinityKey.class}) {
        @Override
        public boolean persistence() {
            return false;
        }

        @Override
        public Factory<? extends ExpiryPolicy> getExpiryPolicyFactory() {
            return null;
        }

        @Override
        public long maxSize() {
            return 1024L * 1024 * 1024;
        }

        @Override
        public int backups() {
            return 0;
        }
    };


    private final String cacheName;
    private final String regionName;

    //   private final int backups;
    private final CacheMode cacheMode;
    private final Class<?>[] indexedTypes;

    IgniteCacheRegion(String cacheName, String regionName, CacheMode cacheMode, Class<?>[] indexedTypes) {
        this.cacheName = cacheName;
        this.regionName = regionName;
        this.cacheMode = cacheMode;
        this.indexedTypes = indexedTypes;
        // this.backups = backups;
    }


    /**
     * 获取缓存名称（用于标识缓存实例）
     *
     * @return 缓存名称
     */
    public String getCacheName() {
        return cacheName;
    }

    /**
     * 获取缓存区域名称
     *
     * @return 区域名称
     */
    public String getRegionName() {
        return regionName;
    }


    /**
     * 获取缓存模式（PARTITIONED 或 REPLICATED）
     *
     * @return 缓存模式
     */
    public CacheMode getCacheMode() {
        return cacheMode;
    }

    /**
     * 获取索引类型数组（用于 Ignite 查询字段索引）
     *
     * @return 索引类型数组
     */
    public Class<?>[] getIndexedTypes() {
        return indexedTypes;
    }


    public abstract boolean persistence();


    public abstract long maxSize();

    public abstract int backups();

    public abstract Factory<? extends ExpiryPolicy> getExpiryPolicyFactory();
}